package com.example.accessibilityhelper.service

import android.animation.ValueAnimator
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.IBinder
import android.util.Log
import android.view.Gravity
import android.view.MotionEvent
import android.view.View
import android.view.WindowManager
import android.widget.ImageView
import androidx.annotation.RequiresApi
import androidx.core.app.NotificationCompat
import com.example.accessibilityhelper.R
import com.example.accessibilityhelper.util.ScreenUtil
import com.lzf.easyfloat.EasyFloat
import com.lzf.easyfloat.anim.DefaultAnimator
import com.lzf.easyfloat.enums.ShowPattern
import com.lzf.easyfloat.enums.SidePattern

class WindowService : Service(), View.OnTouchListener {
    private val TAG = "WindowService"

    val notificationChannelId = "com.hiscrm.notification_channel_id"
    val notificationChannelName = "企业微信助手通知服务"

    lateinit var windowManager: WindowManager
    lateinit var imageView: ImageView
    var lastX = 0f
    var lastY = 0f

    override fun onBind(intent: Intent?): IBinder? {
        return null
    }

    @RequiresApi(Build.VERSION_CODES.O)
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        val notificationChannel = NotificationChannel(
            notificationChannelId,
            notificationChannelName,
            NotificationManager.IMPORTANCE_DEFAULT
        )
        val notificationManager =
            getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.createNotificationChannel(notificationChannel)
        val notification = NotificationCompat.Builder(this, notificationChannelId)
            .setTicker("企业微信悬浮窗服务")
            .setSmallIcon(R.drawable.notifications_active_24)
            .build()
        notificationManager.notify(1, notification)
        startForeground(1, notification)
        createBottomTipFloatWindow()
        createActionFloatWindow(this)
        return super.onStartCommand(intent, flags, startId)
    }


    private fun createBottomTipFloatWindow() {
        EasyFloat.with(this)
            // 设置浮窗xml布局文件，并可设置详细信息
            .setLayout(R.layout.float_window_bottom_tip)
            // 设置浮窗显示类型，默认只在当前Activity显示，可选一直显示、仅前台显示
            .setShowPattern(ShowPattern.ALL_TIME)
            // 设置吸附方式，共15种模式，详情参考SidePattern
            .setSidePattern(SidePattern.RESULT_HORIZONTAL)
            // 设置浮窗的标签，用于区分多个浮窗
            .setTag("testFloat1")
            // 设置浮窗是否可拖拽
            .setDragEnable(false)
            // 浮窗是否包含EditText，默认不包含
            .hasEditText(false)
            // 设置浮窗固定坐标，ps：设置固定坐标，Gravity属性和offset属性将无效
            // 设置浮窗的对齐方式和坐标偏移量
            .setGravity(Gravity.BOTTOM, 0, 0)
            // 设置拖拽边界值
            // 设置宽高是否充满父布局，直接在xml设置match_parent属性无效
            .setMatchParent(widthMatch = true, heightMatch = false)
            // 设置浮窗的出入动画，可自定义，实现相应接口即可（策略模式），无需动画直接设置为null
            .setAnimator(DefaultAnimator())
            // 设置系统浮窗的不需要显示的页面
            // 设置系统浮窗的有效显示高度（不包含虚拟导航栏的高度），基本用不到，除非有虚拟导航栏适配问题
            // 浮窗的一些状态回调，如：创建结果、显示、隐藏、销毁、touchEvent、拖拽过程、拖拽结束。
            // ps：通过Kotlin DSL实现的回调，可以按需复写方法，用到哪个写哪个
            // 创建浮窗（这是关键哦😂）
            .show()
    }

    private fun createActionFloatWindow(context: Context) {
        EasyFloat.with(this)
            // 设置浮窗xml布局文件，并可设置详细信息
            .setLayout(R.layout.float_window)
            // 设置浮窗显示类型，默认只在当前Activity显示，可选一直显示、仅前台显示
            .setShowPattern(ShowPattern.ALL_TIME)
            // 设置吸附方式，共15种模式，详情参考SidePattern
            .setSidePattern(SidePattern.RESULT_HORIZONTAL)
            // 设置浮窗的标签，用于区分多个浮窗
            .setTag("testFloat")
            // 设置浮窗是否可拖拽
            .setDragEnable(true)
            // 浮窗是否包含EditText，默认不包含
            .hasEditText(false)
            // 设置浮窗固定坐标，ps：设置固定坐标，Gravity属性和offset属性将无效
            .setLocation(100, 200)
            // 设置浮窗的对齐方式和坐标偏移量
            .setGravity(Gravity.END or Gravity.CENTER_VERTICAL, 0, 200)
            // 设置拖拽边界值
            // 设置宽高是否充满父布局，直接在xml设置match_parent属性无效
            .setMatchParent(widthMatch = false, heightMatch = false)
            // 设置浮窗的出入动画，可自定义，实现相应接口即可（策略模式），无需动画直接设置为null
            .setAnimator(DefaultAnimator())
            // 设置系统浮窗的不需要显示的页面
            // 设置系统浮窗的有效显示高度（不包含虚拟导航栏的高度），基本用不到，除非有虚拟导航栏适配问题
            // 浮窗的一些状态回调，如：创建结果、显示、隐藏、销毁、touchEvent、拖拽过程、拖拽结束。
            // ps：通过Kotlin DSL实现的回调，可以按需复写方法，用到哪个写哪个
            // 创建浮窗（这是关键哦😂）
            .show()
    }

    override fun onTouch(v: View?, event: MotionEvent): Boolean {
        when (event.actionMasked) {
            MotionEvent.ACTION_DOWN -> {
                lastX = event.rawX
                lastY = event.rawY
                return true
            }
            MotionEvent.ACTION_MOVE -> {
                moveBy(event.rawX - lastX, event.rawY - lastY)
                lastX = event.rawX
                lastY = event.rawY
            }
            MotionEvent.ACTION_UP -> {
                lastX = 0f
                lastY = 0f
                magnetSide(event.rawX, event.rawY)
            }
        }
        return false
    }

    private fun magnetSide(x: Float, y: Float) {
        Log.i(
            TAG,
            "magnetSide: ${imageView.measuredHeight} ${imageView.measuredWidth} ${ScreenUtil.getScreenWidth()} ${ScreenUtil.getScreenHeight()}"
        )
        val finalX = ScreenUtil.getScreenWidth() - imageView.measuredWidth
        val finalY = ScreenUtil.getScreenHeight() / 2f - imageView.measuredHeight / 2

        val animator = ValueAnimator.ofFloat(x, ScreenUtil.getScreenWidth().toFloat())
        animator.duration = 300
        animator.addUpdateListener {
            val animatedValue = it.getAnimatedValue() as Float
            val posY = (imageView.layoutParams as WindowManager.LayoutParams).y.toFloat()
            moveTo(animatedValue, posY)
        }
        animator.start()
    }

    private fun moveBy(deltaX: Float, deltaY: Float) {
        val lp = imageView.layoutParams as WindowManager.LayoutParams
        lp.x += deltaX.toInt()
        lp.y += deltaY.toInt()
        windowManager.updateViewLayout(imageView, lp)
    }

    private fun moveTo(x: Float, y: Float) {
        val lp = imageView.layoutParams as WindowManager.LayoutParams
        lp.x = x.toInt()
        lp.y = y.toInt()
        windowManager.updateViewLayout(imageView, lp)
    }

    override fun onDestroy() {
        super.onDestroy()
    }
}